-- 武圣试炼-副本 逻辑

local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local CopyDefine = require("copy.Define")
local CopyL = require("copy.CopyL")
local WsslConfig = require("excel.Wssl")
local WsslReward = WsslConfig.rank
local WsslMonster = WsslConfig.monster
local Grid = require("bag.Grid")
local Obj = require("core.Obj")
local DailyActFL = require("activity.DailyActFL")
local DailyActDefine = require("activity.Define")
local MailLogic = require("mail.MailLogicFL")
local Lang = require("common.Lang")
local Broadcast = require("broadcast.Broadcast")
local SceneEvent = require("core.SceneEvent")
local ItemDefine = require("bag.ItemDefine")
local RoleFFI =require("role.RoleFFI")

rank_list = rank_list or {}  --排名列表 [roomID] = {}
wssl_data = wssl_data or {}  -- [roomID] = {}
MAX_RANK_VALUE = 20
local NORMAL_REWARD = 12120

--检查是否满足条件
function checkEnter(human)
--    if 1 then return true end
    if not DailyActFL.onCheckActCanJoin(human,DailyActDefine.ACT_TYPE_WSSL_ACT) then
        Broadcast.sendBroadcast(human, Lang.DOWN, Lang.COPY_WSSL_NOT_START)  --活动暂未开启
        return 
    end
    local actData = DailyActFL.onGetActData(DailyActDefine.ACT_TYPE_WSSL_ACT)
    if not actData or actData.status ~= DailyActDefine.ACT_STATE_RUNNING then
        Broadcast.sendBroadcast(human, Lang.DOWN, Lang.COPY_WSSL_NOT_START)  --活动暂未开启
        return
    end 
    if human.db.wsslTime > actData.startTime then
        Broadcast.sendBroadcast(human, Lang.DOWN, Lang.COPY_WSSL_CANT_ENTER)  --只能进一次
        return
    end
    return true
end

--得到活动剩余时间
function getLeftTime()
    local actData = DailyActFL.onGetActData(DailyActDefine.ACT_TYPE_WSSL_ACT)
    if not actData or actData.status ~= DailyActDefine.ACT_STATE_RUNNING then        
        return 0
    end 
    local t =  actData.endTime - os.time()
    if t < 0 then t = 0 end    
    return t, actData.endTime-actData.startTime 
end

--得到排名
function getRank(uuid, roomID)
    if not rank_list[roomID] then
        return
    end
    local list = rank_list[roomID]
    for i = 1, #list do
        if list[i].uuid == uuid then
            return list[i]
        end
    end    
    return
end

function sendRankList(copyID, roomID, human)    
    local msg = Msg.gc.GC_WSSL_RANK
    msg.list[0] = 0
    msg.allJifen = 0
    msg.sumJifen = 0
    if rank_list[roomID] then
      local list  = rank_list[roomID]
      local cnt = #list
      if cnt > MAX_RANK_VALUE then
          cnt = MAX_RANK_VALUE
      end
      for i = 1,  cnt do
        msg.list[i].name = list[i].name
        msg.list[i].uuid = list[i].uuid
        msg.list[i].jifen = list[i].jifen        
      end
      msg.list[0] = cnt
      
      local wssl = wssl_data[roomID]
      local conf = WsslConfig.progress[wssl.wave]
      msg.allJifen = wssl.allJifen
      msg.sumJifen = conf and conf.jifen or 0
    end
    if human then
        Msg.send(msg, human.fd)
    else
        CopyL.sendCopy(msg, copyID, roomID)
    end
end

function sendSelfInfo(human,roomID, data)
    if not data then
        data = getRank(human._id, roomID)
    end
    local wssl = wssl_data[roomID]
    local conf = WsslConfig.progress[wssl.wave]
    local msg = Msg.gc.GC_WSSL_INFO
    msg.jifen = data and data.jifen or 0
    msg.zhangong = data and data.zhangong or 0
    msg.rank = data and data.rank or 0
    msg.monsterLv = conf and conf.power or 1
    msg.allJifen = wssl and wssl.allJifen or 1
    msg.sumJifen = conf and conf.jifen or 1
    msg.exp = data and data.exp or 0
    msg.leftTime = getLeftTime()
    Msg.send(msg, human.fd)
end

--下发奖励列表
RewardListCache = nil
NormalRewardGrid = nil
function checkRewardCache()
   if RewardListCache then
      return
   end
   if RewardListCache == nil then
        RewardListCache = {}
        for k,v in pairs(WsslReward) do
           RewardListCache[k] = {}
           Grid.create(RewardListCache[k], v.reward, 1, true)         
        end
        NormalRewardGrid = {}
        Grid.create(NormalRewardGrid, NORMAL_REWARD, 1, true)
   end
end
function sendRewardList(human)
    local msg = Msg.gc.GC_WSSL_REWARD
    checkRewardCache()
    if msg.rewards[0] == nil then
        for i = 1, #RewardListCache do
           Grid.makeItem(RewardListCache[i], msg.rewards[i])    
        end
        msg.rewards[0] = #RewardListCache
        Grid.makeItem(NormalRewardGrid,msg.normalReward)
     end
     Msg.send(msg, human.fd)
end

function compareRank(a, b)
    if a.jifen > b.jifen then
        return true
    elseif a.jifen < b.jifen then
        return false
    end
    if a.zhandouli > b.zhandouli then
        return true
    elseif a.zhandouli < b.zhandouli then
        return false
    end
    if a.lv > b.lv then
        return true
    elseif a.lv < b.lv then
        return false
    end
    if a.zhangong > b.zhangong then
        return true
    end
    return false
end


function startWave(copyID, roomID, wave)   --开始第几波
    local conf = WsslConfig.progress[wave]
    if not conf then
        return
    end
    wssl_data[roomID] = wssl_data[roomID] or {wave = 1, allJifen = 0}
    wssl_data[roomID].wave = wave
    wssl_data[roomID].allJifen = 0
    for _,sceneID in pairs(CopyL.copyList[copyID][roomID]) do
        SceneEvent.doSceneEvent(sceneID, conf.ref_map)        
    end
end
 
function checkNextWave(copyID, roomID)   --检查是否进入下一波
    local data = wssl_data[roomID]
    if not data then
        return
    end
    local conf = WsslConfig.progress[data.wave]
    if not conf then
        return
    end
    if not WsslConfig.progress[conf.next] then  --没有下一波
        return 
    end
    if conf.jifen <= data.allJifen then
        startWave(copyID, roomID, conf.next)
    end
end

function onWSSLRoomBegin(copyID, roomID)
    startWave(copyID, roomID, 1)   
end

local function addJifen(uuid, name, roomID, jifen, sumExp, zhandouli, lv)
    local rankData = getRank(uuid, roomID)
    if not rankData then
      rank_list[roomID] = rank_list[roomID] or {}
      rankData = {jifen = 0, zhangong = 0, exp = 0, uuid = uuid, name = name, zhandouli = 0, lv = 0}
      rank_list[roomID][ #rank_list[roomID] + 1] = rankData
      rankData.rank = #rank_list[roomID]
    end
    rankData.jifen = rankData.jifen + jifen
    rankData.exp = rankData.exp + sumExp
    rankData.zhandouli = zhandouli
    rankData.lv = lv
    local data = wssl_data[roomID]
    data.allJifen = data.allJifen + jifen
end
function onWSSLMonsterDie(killer, monster, monsterID, copyID, roomID, sumExp)
  local conf = WsslMonster[monster.monster_id]
  if not conf then
      return
  end
  if CopyL.roomDatas[copyID][roomID].finishCode then
      return
  end
  killer = Obj.getOwner(killer) or killer
  if not killer or killer.obj_type ~= Obj.TYPE_HUMAN then
      return
  end
  if killer.db.teamUuidLen > 0 then
    for i = 1, killer.db.teamUuidLen do
         local memberUuid = RoleFFI.ffi_string(killer.db.teamUuid[i - 1].uuid)
         local member = ObjHuman.onlineUuid[memberUuid]
         if member and member.scene_id == monster.scene_id and ObjHuman.getHp(member) > 0 then
            addJifen(memberUuid, member.name, roomID, conf.jifen, sumExp, member.db.zhandouli, member.db.lv)
         end
    end
  else
    addJifen(killer._id, killer.name,roomID, conf.jifen, sumExp,killer.db.zhandouli, killer.db.lv)    
  end
  table.sort(rank_list[roomID], compareRank)
  checkNextWave(copyID, roomID)
  
  local rankChange
  for i = 1,  #rank_list[roomID] do
      if i <= MAX_RANK_VALUE then
          if rank_list[roomID][i].rank ~= i or rank_list[roomID][i].uuid == killer._id then
              rankChange = true
          end         
      end 
       rank_list[roomID][i].rank = i
  end
  if rankChange then
      sendRankList(copyID, roomID)
  end
  sendSelfInfo(killer, roomID, rankData)  
end


--拾取道具
function onWSSLPickUpItem(human, itemID, itemCount, copyID, roomID)--, item)
  if itemID ~= ItemDefine.ITEM_ID_ZHANGONG and itemID ~= ItemDefine.ITEM_ID_ZHANGONG1 then
      return
  end
  local rankData = getRank(human._id, roomID)
  if not rankData then
      return
  end
  rankData.zhangong = rankData.zhangong + itemCount
  sendSelfInfo(human, roomID, rankData)  
end

function onWSSLHumanEnterCopyScene(human, copyID, roomID)--, sceneID)
  sendRankList(copyID, roomID, human)  
  sendSelfInfo(human, roomID)
  sendRewardList(human)  
  human.db.wsslTime = os.time()
end


function onWSSLRoomClear(copyID, roomID)
  rank_list[roomID] = nil
  wssl_data[roomID] = nil
end

function onWSSLTimerTenSec(copyID, roomID)
  sendRankList(copyID, roomID)
end



--活动结束
function onWSSLEnd()--actData, args)
  checkRewardCache()
  local msg = Msg.gc.GC_WSSL_END
  for roomID, data in pairs(rank_list) do 
      table.sort(rank_list[roomID], compareRank)
      
      for i = 1, #data do
          local reward = RewardListCache[i]
          msg.rank = i
          msg.jifen = data[i].jifen
          msg.exp = data[i].exp
          msg.zhangong = data[i].zhangong
          msg.rewards[0] = 0
          
          if reward then
              MailLogic.CreateNewMailForUser(data[i].uuid, Lang.COPY_WSSL_MAIL_TITLE, string.format(Lang.COPY_WSSL_MAIL_CONTENT, i), {[1]=reward})
              
              Grid.makeItem(reward,msg.rewards[1])
              msg.rewards[0] = 1
          elseif data[i].jifen >= 100 then
              MailLogic.CreateNewMailForUser(data[i].uuid, Lang.COPY_WSSL_MAIL_TITLE, Lang.COPY_WSSL_MAIL_CONTENT1, {[1]=NormalRewardGrid})
              Grid.makeItem(NormalRewardGrid,msg.rewards[1])    
              msg.rewards[0] = 1          
          end
          local human = ObjHuman.onlineUuid[data[i].uuid]
          if human and human.fd then
              Msg.send(msg, human.fd)
          end
      end
      CopyL.roomFinish(CopyDefine.COPY_WSSL_ID, roomID, CopyDefine.COPY_FINISH_ACT_END, "活动结束")
  end
end
DailyActFL.onRegisterCallBack(DailyActDefine.ACT_TYPE_WSSL_ACT, nil, nil, onWSSLEnd)
